﻿using System;
using System.Collections.Generic;
using System.Web.Mvc;
using System.Web.Routing;
using UIShell.OSGi;
using UIShell.OSGi.Loader;

namespace Isaac.Joy.Mvc.Web
{
    public class BundleRuntimeControllerFactory : DefaultControllerFactory
    {
        protected override Type GetControllerType(RequestContext requestContext, string controllerName)
        {
            string symbolicName = null;
            object area;
            if (requestContext.RouteData.DataTokens.TryGetValue("area", out area))
            {
                symbolicName = area as string;
            }
            else
            {
                var routeWithArea = requestContext.RouteData.Route as IRouteWithArea;
                if (routeWithArea != null)
                {
                    symbolicName = routeWithArea.Area;
                }
                var castRoute = requestContext.RouteData.Route as Route;
                if (castRoute != null && castRoute.DataTokens != null)
                {
                    symbolicName = castRoute.DataTokens["area"] as string;
                }
            }

            if (symbolicName != null)
            {
                var controllerTypeName = controllerName + "Controller";
                var runtimeService = BundleRuntime.Instance.GetFirstOrDefaultService<IRuntimeService>();
                var assemblies = runtimeService.LoadBundleAssembly(symbolicName);

                foreach (var assembly in assemblies)
                {
                    foreach (var type in assembly.GetTypes())
                    {
                        if (type.Name.ToLower().Contains(controllerTypeName.ToLower()) 
                            && typeof(IController).IsAssignableFrom(type))
                        {
                            return type;
                        }
                    }
                }
            }

            requestContext.RouteData.DataTokens["Namespaces"] = new HashSet<string> { "Isaac.Joy.Mvc.Web.Controllers" };
            return base.GetControllerType(requestContext, controllerName);
        }
    }
}